package request

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"strings"
)

type HttpRequest struct {
	httpRequest *http.Request
	params      map[string]interface{}
}

func NewHttpRequest(r *http.Request) RequestInterface {
	return &HttpRequest{
		httpRequest: r,
	}
}

func (req *HttpRequest) Params(a ...string) interface{} {

	if req.params == nil {

		req.params = map[string]interface{}{}

		_ = req.httpRequest.ParseForm()

		for k, v := range req.httpRequest.Form {
			k = strings.TrimRight(k, "[]")
			if len(v) > 1 {
				req.params[k] = v
			} else {
				req.params[k] = v[0]
			}
		}

		body, _ := ioutil.ReadAll(req.httpRequest.Body)
		_ = json.Unmarshal(body, &req.params)
	}

	key := ""
	def := ""
	switch len(a) {
	case 0:
		return req.params
	case 1:
		key = a[0]
	default:
		key = a[0]
		def = a[1]
	}

	if val, ok := req.params[key]; ok {
		return val
	}

	return def
}

func (req *HttpRequest) ParamsToString(key string, def ...string) string {
	return fmt.Sprintf("%v", req.Params(append([]string{
		key,
	}, def...)...))
}

func (req HttpRequest) Ip() string {
	xForwardedFor := req.httpRequest.Header.Get("X-Forwarded-For")
	ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
	if ip != "" {
		return ip
	}

	ip = strings.TrimSpace(req.httpRequest.Header.Get("X-Real-Ip"))
	if ip != "" {
		return ip
	}

	if ip, _, err := net.SplitHostPort(strings.TrimSpace(req.httpRequest.RemoteAddr)); err == nil {
		return ip
	}

	return ""
}

func (req HttpRequest) Method() string {
	return req.httpRequest.Method
}

func (req HttpRequest) Header(key string) string {
	return req.httpRequest.Header.Get(key)
}

func (req HttpRequest) Cookie(name string) string {
	cookie, e := req.httpRequest.Cookie(name)
	if e != nil {
		return ""
	}
	return cookie.Value
}
